from .models import LoginLog
from .utils import md5_encode
from django.contrib.auth.models import User
from django.contrib.auth import login as _login, logout
from datetime import datetime


def get_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        # 所以这里是真实的ip
        ip = x_forwarded_for.split(',')[0]
    else:
        # 这里获得代理ip
        ip = request.META.get('REMOTE_ADDR')
    return ip


def get_broser_validate_code(request):
    """
    使用客户端的浏览器信息与ip加密作为校验用户有效性的依据
    :param request:
    :return:
    """
    wait_str = request.META['HTTP_USER_AGENT'] + get_ip(request)
    return md5_encode(wait_str)


def set_login(request, user):
    """
    设置指定的用户为登陆状态
    :param request:
    :param user:
    :return:
    """
    token = md5_encode(user.username + str(int(datetime.now().timestamp() * 1000000)))
    vcode = get_broser_validate_code(request)
    # 保存登录信息前把该用户在该浏览器该ip下的登录信息设为作废
    LoginLog.objects.filter(username=user.username, validate_code=vcode, is_del=0).update(is_del=1)
    result = LoginLog.objects.create(token=token, username=user.username, validate_code=vcode)
    if result:
        return token
    return ""


def get_login_user(request, token):
    """
    验证指定token相关的登陆状态。若已登录则返回用户，
    :param request:
    :param token:
    :return:
    """
    login_log = LoginLog.objects.filter(token=token, is_del=0)
    if login_log:
        data = login_log[0]
        vcode = get_broser_validate_code(request)
        # 发起请求的客户端信息与登录时的记录不一致
        if data.validate_code != vcode:
            return None
        # 设置用户为登陆状态
        user = User.objects.filter(username=data.username)
        _login(request, user)
        return user
    return None


def is_login(request, token):
    """
    验证是否登录
    :param request:
    :param token:
    :return:
    """
    vcode = get_broser_validate_code(request)
    login_log = LoginLog.objects.filter(token=token, validate_code=vcode, is_del=0)
    if login_log:
        lu = login_log[0]
        if not request.user.is_authenticated:
            user = User.objects.filter(username=lu.username)
            if not user:
                return False
            _login(request, user[0])
        return True

    return False


def set_logout(request, token):
    """
    退出登录。先清空登陆状态。再清空该浏览器登陆数据
    :param request:
    :param token:
    :return:
    """
    if request.user.is_authenticated:
        logout(request)
    LoginLog.objects.filter(token=token, validate_code=get_broser_validate_code(request), is_del=0).update(is_del=1)
